
#ifndef __BOCAT_COMMON_BASE64_HPP_2010__
#define __BOCAT_COMMON_BASE64_HPP_2010__

#include <string>
#include <iostream>

#include "boost/archive/iterators/base64_from_binary.hpp"
#include "boost/archive/iterators/binary_from_base64.hpp"
#include "boost/archive/iterators/transform_width.hpp"

//using namespace std;
//using namespace boost::archive::iterators;

namespace	bocat	{
namespace	common	{


template<typename InputContainerType>
inline std::string base64_encode(const InputContainerType & cont)
{
        using namespace boost::archive::iterators;
        typedef base64_from_binary< transform_width< typename InputContainerType::const_pointer, 6, 8 > > base64_t;

        std::string str = std::string(base64_t(&cont[0]), base64_t(&cont[0] + cont.size()));

		size_t	pad_size = 4 - (str.size() % 4);
		if (pad_size < 4) {
			str.append(pad_size, '=');
		}

        return str;
}

inline std::string base64_encode(const char* p, size_t sz)
{
        using namespace boost::archive::iterators;
        typedef base64_from_binary< transform_width< char*, 6, 8 > > base64_t;

        std::string str = std::string(base64_t(p), base64_t(p + sz));

		size_t	pad_size = 4 - (str.size() % 4);
		if (pad_size < 4) {
			str.append(pad_size, '=');
		}

        return str;
}


///////////////////////////////////////////////////////////////////////
//


template<typename Container, typename CharT>
inline Container base64_decode(std::basic_string<CharT> str)
{
        typedef boost::archive::iterators::transform_width< boost::archive::iterators::binary_from_base64<CharT *>, 8, 6 > binary_t;

        typename std::basic_string<CharT>::size_type pos = str.find_last_not_of(CharT('='));
        pos = (pos == str.size() -1 ? str.size() : pos );

        return Container(binary_t(&str[0]), binary_t(&str[0] + pos));
}

}	//// namespace	bocat
}	//// namespace	common


#endif // __BOCAT_COMMON_BASE64_HPP_2010__




